﻿using AutoMapper;
using ManagementApi.Authorizers;
using ManagementApi.Models;
using ManagementApi.Models.Commander;
using ManagementApi.Models.Project;
using ManagementApi.Mvc;
using ManagementApi.Mvc.ApplicationContexts;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Modules;
using Modules.Commander;
using Modules.Project;
using PmSoft.Entity;
using PmSoft.Exceptions;
using PmSoft.Utilities;

namespace ManagementApi.Controllers.ConstructorPannel
{
    /// <summary>
    /// 建设单位-指挥部信息管理
    /// </summary>
    [Route("/api/v1/constructor/commander")]
    [ApiController]
    [Authorize(Roles = "Constructor")]
    public class CommanderController : ControllerBase
    {
        private readonly CommanderService commanderService;
        private readonly CommanderProjectService commanderProjectService;
        private readonly ConstructorApplicationContext applicationContext;
        private readonly IMapper mapper;
        private readonly ProjectCorpService projectCorpService;

        public CommanderController(CommanderService commanderService, ConstructorApplicationContext applicationContext, IMapper mapper, CommanderProjectService commanderProjectService, ProjectCorpService projectCorpService)
        {
            this.commanderService = commanderService;
            this.applicationContext = applicationContext;
            this.mapper = mapper;
            this.commanderProjectService = commanderProjectService;
            this.projectCorpService = projectCorpService;
        }

        /// <summary>
        /// 新增指挥部信息
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [HttpPost("create")]
        public ApiResult CreateCommander(CommanderCreateForm form)
        {
            CommanderInfo commanderInfo = new CommanderInfo();
            mapper.Map(form, commanderInfo);
            if (applicationContext.CurrentUser != null)
                commanderInfo.ConstructorId = applicationContext.CurrentUser.Id;
            commanderInfo.CreateTime = DateTime.Now;
            commanderService.CreateCommander(commanderInfo, form.Password);
            return ApiResult.Success("创建成功");
        }

        /// <summary>
        /// 编辑指挥部信息
        /// </summary>
        /// <param name="commanderId"></param>
        /// <param name="form"></param>
        /// <returns></returns>
        [HttpPut("{commanderId}")]
        public ApiResult UpdateCommander(int commanderId, CommanderEditForm form)
        {
            if (applicationContext.CurrentUser == null) throw new BusinessException("登录信息错误");
            CommanderInfo? commanderInfo = commanderService.GetCommanderInfo(commanderId);
            if (commanderInfo == null)
                return ApiResult.Failure("指挥部信息不存在");
            if (commanderInfo.ConstructorId != applicationContext.CurrentUser.Id) throw new BusinessException("暂无改指挥部操作权限,请联系管理员");

            mapper.Map(form, commanderInfo);
            commanderService.UpdateCommander(commanderInfo);
            return ApiResult.Success("修改成功");
        }

        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="commanderId"></param>
        /// <param name="password"></param>
        /// <returns></returns>
		[HttpPatch("{commanderId}/password")]
        public ApiResult UpdatePassword(int commanderId, string password)
        {
            if (applicationContext.CurrentUser == null) throw new BusinessException("登录信息错误");
            CommanderInfo? commanderInfo = commanderService.GetCommanderInfo(commanderId);
            if (commanderInfo == null)
                return ApiResult.Failure("指挥部信息不存在");
            if (commanderInfo.ConstructorId != applicationContext.CurrentUser.Id) throw new BusinessException("暂无改指挥部操作权限,请联系管理员");
            commanderService.UpdatePassword(commanderId, password);
            return ApiResult.Success("密码重置成功");
        }

        /// <summary>
        /// 删除指挥部
        /// </summary>
        /// <param name="commanderIds"></param>
        /// <returns></returns>
        [HttpDelete("{commanderIds}")]
        public ApiResult Delete(string commanderIds)
        {
            if (applicationContext.CurrentUser == null) throw new BusinessException("登录信息错误");
            var datas = commanderService.GetCommanderInfos(ValueUtility.ConvertToList<int>(commanderIds));
            if (datas.Any(i => i.ConstructorId != applicationContext.CurrentUser.Id)) throw new BusinessException("暂无改指挥部操作权限,请联系管理员");
            commanderService.DeleteCommanderIds(ValueUtility.ConvertToList<int>(commanderIds));
            return ApiResult.Success("删除成功");
        }

        /// <summary>
        /// 获取指挥部列表(分页)
        /// </summary>
        /// <param name="query">查询条件</param>
        /// <param name="pageNum">页码</param>
        /// <param name="pageSize">每页数量</param>
        /// <returns></returns>
        [HttpGet("page")]
        public ApiResult<PageDto<CommanderDto>> GetWagePayrolls([FromQuery] CommanderQuery query, int pageNum = 1, int pageSize = 20)
        {
            query.ConstructorId = applicationContext.CurrentUser?.Id;
            var data = commanderService.GetCommanders(query, pageNum, pageSize);
            var dtos = data.AsPageDto(source => { return source.AsDto(applicationContext); });
            return ApiResult<PageDto<CommanderDto>>.Success(dtos);
        }

        /// <summary>
        /// 指挥部表单数据
        /// </summary>
        /// <param name="commanderId"></param>
        /// <returns></returns>
        [HttpGet("{commanderId}/form")]
        public ApiResult<CommanderEditForm> GetProject(int commanderId)
        {
            var data = commanderService.GetCommanderInfo(commanderId);
            if (data == null)
                return ApiResult<CommanderEditForm>.Failure("指挥部数据不存在");
            CommanderEditForm commanderEditForm = new CommanderEditForm();
            mapper.Map(data, commanderEditForm);
            return ApiResult<CommanderEditForm>.Success(commanderEditForm);
        }

        /// <summary>
        /// 项目配置
        /// </summary>
        /// <param name="commanderId"></param>
        /// <param name="form"></param>
        /// <returns></returns>
        [HttpPost("saveCommanderProject/{commanderId}")]
        public ApiResult SaveCommanderProject(int commanderId, IEnumerable<CommanderProjectEditForm> form)
        {
            if (applicationContext.CurrentUser == null) throw new BusinessException("登录信息错误");

            var commanderInfo = commanderService.GetCommanderInfo(commanderId);
            if (commanderInfo == null)
                return ApiResult.Failure("指挥部数据不存在");
            if (commanderInfo.ConstructorId != applicationContext.CurrentUser.Id)
                return ApiResult.Failure("暂无改指挥部操作权限,请联系管理员");

            var projectInfos = applicationContext.GetService<ProjectService>().GetProjectInfosByConstructorId(commanderInfo.ConstructorId);

            List<CommanderProject> commanderProjects = new();
            foreach (var item in form)
            {
                if (!projectInfos.Any(s => s.ProjectId == item.ProjectId))
                    throw new OwnAuthorizationFailedException();

                if (commanderProjects.Any(m => m.ProjectId == item.ProjectId))
                    return ApiResult.Failure("不允许配置重复项目");

                CommanderProject commanderProject = new()
                {
                    ProjectId = item.ProjectId,
                    CommanderId = commanderId
                };
                commanderProjects.Add(commanderProject);
            }
            commanderProjectService.CreateOrUpdate(commanderId, commanderProjects);
            return ApiResult.Success("配置成功");
        }

        /// <summary>
        /// 根据指挥部id查询项目集合
        /// </summary>
        /// <param name="commanderId"></param>
        /// <returns></returns>
        [HttpGet("CommanderProjects/{commanderId}")]
        public ApiResult<IEnumerable<CommanderProjectEditForm>> GetCommanderProject(int commanderId)
        {
            var data = commanderProjectService.GetCommanderProjectsByCommanderId(commanderId);
            return ApiResult<IEnumerable<CommanderProjectEditForm>>.Success(data.AsForm(applicationContext));
        }
    }
}